package javaMSCRM;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JTextField;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumnModel;

import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlString;

import com.microsoft.schemas.crm._2006.query.AllColumns;
import com.microsoft.schemas.crm._2006.query.ArrayOfAnyType;
import com.microsoft.schemas.crm._2006.query.ArrayOfConditionExpression;
import com.microsoft.schemas.crm._2006.query.ArrayOfOrderExpression;
import com.microsoft.schemas.crm._2006.query.ConditionExpression;
import com.microsoft.schemas.crm._2006.query.FilterExpression;
import com.microsoft.schemas.crm._2006.query.LogicalOperator;
import com.microsoft.schemas.crm._2006.query.OrderExpression;
import com.microsoft.schemas.crm._2006.query.OrderType;
import com.microsoft.schemas.crm._2006.query.PagingInfo;
import com.microsoft.schemas.crm._2006.query.QueryExpression;
import com.microsoft.schemas.crm._2006.webservices.BusinessEntityCollection;
import com.microsoft.schemas.crm._2007.webservices.RetrieveMultipleDocument;
import com.microsoft.schemas.crm._2007.webservices.RetrieveMultipleDocument.RetrieveMultiple;
/**
 * @author Zoran IVANOV
 *
 */
public class Entities {
	JavaMSCRM JavaMSCRM = null;
	int pageNumber = 0;
	String[] ColumnEntitiesNames = {};
	String[] ColumnEntitiesTitles = {};
	String[] ViewFilterLabels = {};
	Condition[] MSCRMConditions = {};
	int SortingColumn = 0;
	int SortingDirection = 1;
	String letterFilter = "";
	PagingInfo pageInfo = null;
	boolean viewFilter = true;
	String searchString = "";
	String Entity = "";
	String ViewTitle = "";

	/**
	 * @param mSCRMConditions
	 */
	public void setMSCRMConditions(Condition[] mSCRMConditions) {
		MSCRMConditions = mSCRMConditions;
	}
	
	/**
	 * @param columnEntitiesNames
	 */
	public void setColumnEntitiesNames(String[] columnEntitiesNames) {
		ColumnEntitiesNames = columnEntitiesNames;
	}


	/**
	 * @param columnEntitiesTitles
	 */
	public void setColumnEntitiesTitles(String[] columnEntitiesTitles) {
		ColumnEntitiesTitles = columnEntitiesTitles;
	}


	/**
	 * @param viewFilterLabels
	 */
	public void setViewFilterLabels(String[] viewFilterLabels) {
		ViewFilterLabels = viewFilterLabels;
	}
	
	/**
	 * @param JavaMSCRM
	 */
	public Entities(JavaMSCRM JavaMSCRM) {
		this.JavaMSCRM = JavaMSCRM;
		JavaMSCRM.Entity = this.Entity;		
		JavaMSCRM.EntriesIDList = new ArrayList<String>();
		JavaMSCRM.NewEntryJB.setVisible(true);
		JavaMSCRM.DeleteEntryJB.setVisible(true);
		JavaMSCRM.SearchContainer.setVisible(true);
		JavaMSCRM.HeaderBarContainerMiddle.setVisible(true);
		//Clear New and Delete Action Listeners
		ActionListener[] JBALS = JavaMSCRM.NewEntryJB.getActionListeners();
		for(int i=0; i<JBALS.length; i++){  
			JavaMSCRM.NewEntryJB.removeActionListener(JBALS[i]);
        }
		JavaMSCRM.NewEntryJB.addActionListener(JavaMSCRM);
		ActionListener[] JBALS1 = JavaMSCRM.DeleteEntryJB.getActionListeners();
		for(int i=0; i<JBALS1.length; i++){  
			JavaMSCRM.DeleteEntryJB.removeActionListener(JBALS1[i]);
        }
		JavaMSCRM.DeleteEntryJB.addActionListener(JavaMSCRM);
		JavaMSCRM.SearchField.setText("");
	}
	
	/**
	 * @param button
	 * @param letterFilter
	 * @param al
	 */
	public void setLetterButton(JButton button, final String letterFilter, final Entities al){
		ActionListener[] ActionListenersList = button.getActionListeners();
		for(int i=0; i<ActionListenersList.length; i++){
			button.removeActionListener(ActionListenersList[i]);
	    }
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				al.letterFilter = letterFilter;
				al.displayEntitiesList(null, SortingColumn, SortingDirection, letterFilter);
		}
	});
	}
	
	/**
	 * @param al
	 */
	public void displayLetterFilters(final Entities al){
		setLetterButton(JavaMSCRM.ButtonAll, "", al);
    	setLetterButton(JavaMSCRM.ButtonA, "A", al);
    	setLetterButton(JavaMSCRM.ButtonB, "B", al);
    	setLetterButton(JavaMSCRM.ButtonC, "C", al);
    	setLetterButton(JavaMSCRM.ButtonD, "D", al);
    	setLetterButton(JavaMSCRM.ButtonE, "E", al);
    	setLetterButton(JavaMSCRM.ButtonF, "F", al);
    	setLetterButton(JavaMSCRM.ButtonG, "G", al);
    	setLetterButton(JavaMSCRM.ButtonH, "H", al);
    	setLetterButton(JavaMSCRM.ButtonI, "I", al);
    	setLetterButton(JavaMSCRM.ButtonJ, "J", al);
    	setLetterButton(JavaMSCRM.ButtonK, "K", al);
    	setLetterButton(JavaMSCRM.ButtonL, "L", al);
    	setLetterButton(JavaMSCRM.ButtonM, "M", al);
    	setLetterButton(JavaMSCRM.ButtonN, "N", al);
    	setLetterButton(JavaMSCRM.ButtonO, "O", al);
    	setLetterButton(JavaMSCRM.ButtonP, "P", al);
    	setLetterButton(JavaMSCRM.ButtonQ, "Q", al);
    	setLetterButton(JavaMSCRM.ButtonR, "R", al);
    	setLetterButton(JavaMSCRM.ButtonS, "S", al);
    	setLetterButton(JavaMSCRM.ButtonT, "T", al);
    	setLetterButton(JavaMSCRM.ButtonU, "U", al);
    	setLetterButton(JavaMSCRM.ButtonV, "V", al);
    	setLetterButton(JavaMSCRM.ButtonW, "W", al);
    	setLetterButton(JavaMSCRM.ButtonX, "X", al);
    	setLetterButton(JavaMSCRM.ButtonY, "Y", al);
    	setLetterButton(JavaMSCRM.ButtonZ, "Z", al);
	}
	
	/**
	 * @param fetchNext
	 * @param CurrentPageNumber
	 * @param al
	 * @param letterFilter
	 */
	public void pagesNavigation(boolean fetchNext, int CurrentPageNumber, final Entities al, final String letterFilter ){
		//Previous Page
        if(CurrentPageNumber > 1){
        	ActionListener[] JBALS = JavaMSCRM.PreviousPage.getActionListeners();
    		for(int i=0; i<JBALS.length; i++){  
    			JavaMSCRM.PreviousPage.removeActionListener(JBALS[i]);
            }
        	JavaMSCRM.PreviousPage.addActionListener(new ActionListener() {
    			public void actionPerformed(ActionEvent e) {
    				pageInfo.setPageNumber(pageInfo.getPageNumber()-2);
    				al.displayEntitiesList(pageInfo, SortingColumn, SortingDirection, letterFilter);
    			}
    		});
        	JavaMSCRM.PreviousPage.setVisible(true);
        }else{
        	JavaMSCRM.PreviousPage.setVisible(false);
        }
        
        //Next Page
        final PagingInfo pageInfoNextFinal = pageInfo;
        int NextPageNumber = CurrentPageNumber+1;
        pageInfoNextFinal.setPageNumber(NextPageNumber);
        
        if(fetchNext){
        	ActionListener[] JBALS = JavaMSCRM.NextPage.getActionListeners();
    		for(int i=0; i<JBALS.length; i++){  
    			JavaMSCRM.NextPage.removeActionListener(JBALS[i]);
            }
        	JavaMSCRM.NextPage.addActionListener(new ActionListener() {
    			public void actionPerformed(ActionEvent e) {
    				al.displayEntitiesList(pageInfoNextFinal, SortingColumn, SortingDirection, letterFilter);
    			}
    		});
        	JavaMSCRM.NextPage.setVisible(true);
        }else{
        	JavaMSCRM.NextPage.setVisible(false);
        }
	}
	
	/**
	 * @param al
	 * @param combo
	 */
	public void initialiseSearchForm(final Entities al, final JComboBox combo){
		//Search
		ActionListener[] JBALS = JavaMSCRM.SearchButton.getActionListeners();
		for(int i=0; i<JBALS.length; i++){  
			JavaMSCRM.SearchButton.removeActionListener(JBALS[i]);
        }
		
		final JButton searchButton = JavaMSCRM.SearchButton;
		final JTextField searchField = JavaMSCRM.SearchField;
		searchButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				searchString = searchField.getText();
				if(!searchString.equals("")){
					al.viewFilter = false;
					if(!combo.getSelectedItem().equals("Search Results"))
						combo.addItem("Search Results");
					combo.setSelectedItem("Search Results");
					al.displayEntitiesList(null, 0, 1, "");
				}
			}
		});	
	}
	
	/**
	 * @param al
	 * @param combo
	 * @param SearchFieldFinal
	 */
	public void initialiseViewComboBox(final Entities al, final JComboBox combo, final JTextField  SearchFieldFinal){
		//Set Filter View
		ActionListener[] JCBALS = JavaMSCRM.ViewFilterJCB.getActionListeners();
		for(int i=0; i<JCBALS.length; i++){  
			JavaMSCRM.ViewFilterJCB.removeActionListener(JCBALS[i]);
        }
		
		JavaMSCRM.ViewFilterJCB.removeAllItems();
		for(int i=0; i<ViewFilterLabels.length; i++){
			JavaMSCRM.ViewFilterJCB.addItem(ViewFilterLabels[i]);
		}

		JavaMSCRM.ViewFilterContainer.setVisible(true);

		combo.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				String selectedItem = (String)combo.getSelectedItem();
				for(int i=0; i<ViewFilterLabels.length; i++){
					if(selectedItem.equals(ViewFilterLabels[i])){
						if(i == 1)
							al.viewFilter = false;
						else if(i == 0)
							al.viewFilter = true;
		            	searchString = "";
		            	SearchFieldFinal.setText("");
		            	combo.removeItem("Search Results");
		            	al.displayEntitiesList(null, 0, 1, "");
		            }
				}
			}
		});
	}
	
	/**
	 * @param bec
	 */
	public void initialiseLetterFilterAndNavigation(BusinessEntityCollection bec){
		//Display Letters Filters
    	displayLetterFilters(this);
        		        
        //Page Number
        int CurrentPageNumber = this.pageInfo.getPageNumber();
        JavaMSCRM.PageNumber.setText("Page "+Integer.toString(CurrentPageNumber));
        
        //Pages Navigation
        pagesNavigation(bec.getMoreRecords(), CurrentPageNumber, this, letterFilter);
        
	}
	
	/**
	 * @param al
	 * @param letterFilter
	 */
	public void displayTableHeader(final Entities al, final String letterFilter){
		String iconUp = " ▲";
        String iconDown = " ▼";
        
        JavaMSCRM.clearTable();
        for(int i=0; i<ColumnEntitiesTitles.length; i++){
        	if((SortingColumn == i)){
            	if(SortingDirection == 1)
            		JavaMSCRM.model.addColumn(ColumnEntitiesTitles[i]+iconDown);
            	else
            		JavaMSCRM.model.addColumn(ColumnEntitiesTitles[i]+iconUp);	
            }else{
            	JavaMSCRM.model.addColumn(ColumnEntitiesTitles[i]);
            }
        }
        
        //Set Action Listeners for Sorting
        
        JTableHeader tableHeader = JavaMSCRM.table.getTableHeader();	
        tableHeader.setFont(new Font("Arial", Font.BOLD, 12));
        tableHeader.addMouseListener(new MouseAdapter(){
	        public void mouseClicked(MouseEvent e){
	        	TableColumnModel columnModel = JavaMSCRM.table.getColumnModel();
	            int viewColumn = JavaMSCRM.table.columnAtPoint(e.getPoint());
	            if((SortingColumn == columnModel.getColumn(viewColumn).getModelIndex()) && (SortingDirection == 1)){
	            	SortingDirection = 2;
	            }else{
	            	SortingDirection = 1;
	            }
	            	
	            SortingColumn = columnModel.getColumn(viewColumn).getModelIndex();
	            al.displayEntitiesList(null, SortingColumn, SortingDirection, letterFilter);
	         }
	        } );
	}
	
	/**
	 * @param pageInfo
	 * @return com.microsoft.schemas.crm._2007.webservices.RetrieveMultipleDocument
	 */
	public RetrieveMultipleDocument getListOfEntities(PagingInfo pageInfo){
		//Order
        ArrayOfOrderExpression orders = ArrayOfOrderExpression.Factory.newInstance();
        OrderExpression order1 = orders.insertNewOrder(0);
        
        //order1.setAttributeName("name");
        order1.setAttributeName(ColumnEntitiesNames[SortingColumn]);
        order1.setOrderType(OrderType.Enum.forInt(SortingDirection));
        orders.setOrderArray(0,order1);
        
        //Criteria
        FilterExpression criteria = FilterExpression.Factory.newInstance();
        ArrayOfConditionExpression conditions = criteria.addNewConditions(); 
        //Apply Conditions
        for(int i=0; i < MSCRMConditions.length; i++){
        	Condition currentMSCRMCondition = MSCRMConditions[i];
        	if(currentMSCRMCondition.applicationCondition){   
    	        ConditionExpression cExpression = conditions.addNewCondition();
    	        cExpression.setAttributeName(currentMSCRMCondition.attributeName);   
    	        cExpression.setOperator(currentMSCRMCondition.ConditionOperator);
    	        ArrayOfAnyType cValues = cExpression.addNewValues();
    	        cValues.addNewValue();
    	        XmlObject value = XmlString.Factory.newValue(currentMSCRMCondition.value);
    	        cValues.setValueArray(0, value);
            }
        }
       
        criteria.setFilterOperator(LogicalOperator.AND);
        criteria.setConditions(conditions);
        
        QueryExpression query = QueryExpression.Factory.newInstance();
        // Initialize the page number.
    	if(pageInfo == null){
    		this.pageInfo = query.addNewPageInfo();
    		this.pageInfo.setPageNumber(1);
    		this.pageInfo.setCount(JavaMSCRM.recordsPerPage);
    		this.pageInfo.setPagingCookie(null);
		}
    	
    	//Setup the query
        query.setCriteria(criteria);
        query.setDistinct(false);
        query.setColumnSet(AllColumns.Factory.newInstance());  
        query.setEntityName(this.Entity);
        query.setPageInfo(this.pageInfo);
        query.setOrders(orders);
        
        RetrieveMultipleDocument rmd = RetrieveMultipleDocument.Factory.newInstance();  
        RetrieveMultiple rm = RetrieveMultiple.Factory.newInstance();
        rm.setQuery(query);
        rmd.setRetrieveMultiple(rm);
		return rmd;
	}
	
	/**
	 * @param pageInfo
	 * @param sortingColumn
	 * @param sortingDirection
	 * @param letterFilter
	 */
	public void displayEntitiesList(PagingInfo pageInfo, int sortingColumn, int sortingDirection, String letterFilter){
		
	}
}
